﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DDay.iCal;
using DDay.iCal.Components;
using DDay.iCal.DataTypes;

using IView.DiaryAndTracking;
using Presenter.DiaryAndTracking;
using DataTransferObject.DiaryAndTrackingTask.SupportClassForDiary;
using System.Reflection;

namespace JSKE.DiaryAndTracking
{
    public partial class DiaryForm : FormLang, IDiaryForm
    {
        private const int NUM_OF_COLUMNS = 11;
        private const int EVENT_ID_COL = 0;
        private const int EVENT_START_COL = 1;
        private const int EVENT_TYPE_COL = 2;
        private const int EVENT_NAME_COL = 3;

        private PresenterDiaryForm _presenter;
        private DateTime _viewFrom = DateTime.Now.Date;
        private DateTime _viewTo = DateTime.Now.Date;
        private List<JskeEvent> jskeEvents = new List<JskeEvent>();
        private JskeEvent currentSelectedEvent = new JskeEvent();
        private List<int> listDeletedEventID = new List<int>();
        private List<int> listNewEventID = new List<int>();

        private int currentSelectedItem = -1;

        private Boolean isDataChanged = false;
        public DiaryForm()
        {
            //InitializeComponent();
            
            _presenter = new PresenterDiaryForm(this, DATA_MODE);
            
            cbbViewEventTime.SelectedIndex = 1;
            jskeEvents = _presenter.getListJskeEvent(_viewFrom, _viewTo);
            BindListView(jskeEvents);
            cbbPriority.DataSource = null;
            cbbPriority.DataSource = Enum.GetValues(typeof(EventPriority));
            cbbSatisfy.DataSource = Enum.GetValues(typeof(EventSatsified));
            cbbPriority.SelectedIndex = 0;
            btnInsertEvent.Enabled = true;
            btnUpdate.Enabled = false;
        }
        public DiaryForm(string message)
        {
            //InitializeComponent();
        }
        private void btnAnalyze_Click(object sender, EventArgs e)
        {
            
            DiaryAnalyzeForm diaryAnalyzeForm = new DiaryAnalyzeForm();;
            if (jskeEvents.Count > 0)
            {
                DialogResult dlrst = MessageBox.Show("Do you want to analyze the current Diary?", "Notice", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (dlrst == DialogResult.Yes)
                {
                    diaryAnalyzeForm = new DiaryAnalyzeForm(jskeEvents, dtpkViewFrom.Value, dtpkViewTo.Value);
                }
                else
                {
                    diaryAnalyzeForm = new DiaryAnalyzeForm();
                }
            }
            diaryAnalyzeForm.ShowDialog(this);
        }

        private void btnWhy_Click(object sender, EventArgs e)
        {
            //QuestionaireForm questionForm = new QuestionaireForm();
            //questionForm.ShowDialog(this);
        }

        private void dtpkViewTo_ValueChanged(object sender, EventArgs e)
        {
            if (dtpkViewTo.Value <= dtpkViewFrom.Value)
            {
                MessageBox.Show("Invalid time", "From Time must be smaller than To Time", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        private void btnViewDiary_Click(object sender, EventArgs e)
        {
            jskeEvents = _presenter.getListJskeEvent(dtpkViewFrom.Value.Date, dtpkViewTo.Value.Date);
            BindListView(jskeEvents);
        }
        private void BindListView(List<JskeEvent> list)
        {
            dtgrvListEvents.SuspendLayout();

            dtgrvListEvents.Items.Clear();

            foreach (JskeEvent evt in list)
            {
                ListViewItem item = new ListViewItem(new string[]{evt.EventStart.ToString(),
                                    evt.EventType.ToString(),
                                    evt.EventName.ToString(),
                                    evt.EventDuration.ToString(),
                                    evt.EventPriority.ToString(),
                                    evt.EventSatisfy.ToString(),
                                    Convert.ToString(evt.TaskName),
                                    Convert.ToString(evt.ProjectName),
                                    Convert.ToString(evt.WorkingHourName),
                                    evt.TaskPriority.ToString(),
                                    Convert.ToString(evt.Money)});
                dtgrvListEvents.Items.Add(item);
            }
            if (this.currentSelectedItem > -1)
            {
                dtgrvListEvents.Items[this.currentSelectedItem].Selected = true;
            }
            dtgrvListEvents.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
            dtgrvListEvents.ResumeLayout();
        }
        private void btnDeleteSelEvts_Click(object sender, EventArgs e)
        {
            DialogResult dlgResult = MessageBox.Show("Do you want to delete these events?",
                "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

            if ((dlgResult.ToString()).Equals("Yes"))
            {
                                
                JskeEvent evt = currentSelectedEvent;
                if (evt != null)
                {
                    List<JskeEvent> listEventTobeDone = new List<JskeEvent>();
                    this.currentSelectedItem -= dtgrvListEvents.SelectedIndices.Count;
                    for (int i = 0; i < dtgrvListEvents.SelectedIndices.Count; i++)
                    {
                        JskeEvent delEvt = jskeEvents[dtgrvListEvents.SelectedIndices[i] -i];
                        listDeletedEventID.Add(delEvt.EventID);
                        jskeEvents.Remove(delEvt);
                        if (listNewEventID.Contains(delEvt.EventID))
                        {
                            listNewEventID.Remove(delEvt.EventID);
                        }

                    }
                    BindListView(jskeEvents);
                    isDataChanged = true;
                }
            }
            
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            doSaveDiary();
        }

        private void doSaveDiary()
        {
            try
            {
                _presenter.saveListResult(jskeEvents, listDeletedEventID, listNewEventID, currentEventType);
                MessageBox.Show("The Diary was successfully saved!", "Notice", MessageBoxButtons.OK, MessageBoxIcon.Information);
                isDataChanged = false;
            }
            catch (Exception ex)
            {
                MessageBox.Show("There was an error while trying to save the Diary: " + ex.Message,
                    "Notice", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

        private void btnUpdate_Click(object sender, EventArgs e)
        {
            try
            {
                currentSelectedEvent.Money = Double.Parse(txtMoney.Text);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Money must be a number: " + ex.Message, "Notice", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }
            currentSelectedEvent.EventDuration = int.Parse(txtDuration.Text);
            txtDuration.Text = "";
            currentSelectedEvent.EventName = txtEventName.Text;
            txtEventName.Text = "";
            currentSelectedEvent.EventPriority = (EventPriority)cbbPriority.SelectedIndex;
            currentSelectedEvent.EventSatisfy = (EventSatsified)cbbSatisfy.SelectedIndex;
            //cbbPriority.SelectedIndex = 0;
            currentSelectedEvent.EventStart = dtpkStart.Value;
            //dtpkStart.Value = DateTime.Now;
            currentSelectedEvent.EventType = cbbEventType.Text;
            currentEventType.Add(cbbEventType.Text);
            loadEventTypeData(currentEventType);
            cbbEventType.Text = currentSelectedEvent.EventType;

            //cbbEventType.SelectedIndex = 0;
            BindListView(jskeEvents);
            btnUpdate.Enabled = false;
            btnInsertEvent.Enabled = true;
            isDataChanged = true;
        }

        #region IDiaryForm

        EventType currentEventType;
        public void loadEventTypeData(EventType eventTypeData)
        {
            cbbEventType.DataSource = null;
            cbbEventType.DataSource = eventTypeData.TypeName;
            cbbEventType.SelectedIndex = 0;
            currentEventType = eventTypeData;
        }
        #endregion

        private void btnInsertEvent_Click(object sender, EventArgs e)
        {
            JskeEvent newEvt = new JskeEvent();
            try
            {
                newEvt.Money = Double.Parse(txtMoney.Text);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Money must be a number: " +ex.Message, "Notice", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            newEvt.EventDuration = int.Parse(txtDuration.Text);
            txtDuration.Text = "";
            newEvt.EventName = txtEventName.Text;
            txtEventName.Text = "";
            newEvt.EventPriority = (EventPriority)cbbPriority.SelectedIndex;
            newEvt.EventSatisfy = (EventSatsified)cbbSatisfy.SelectedIndex;
            cbbPriority.SelectedIndex = 0;
            newEvt.EventStart = dtpkStart.Value;
            dtpkStart.Value = DateTime.Now;
            newEvt.EventType = cbbEventType.Text;
            currentEventType.Add(cbbEventType.Text);
            loadEventTypeData(currentEventType);
            cbbEventType.Text = currentSelectedEvent.EventType;

            cbbEventType.SelectedIndex = 0;
            btnUpdate.Enabled = false;
            btnInsertEvent.Enabled = true;

            newEvt.EventID = DateTime.Now.GetHashCode();
            if (!listNewEventID.Contains(newEvt.EventID))
            {
                listNewEventID.Add(newEvt.EventID);
            }

            jskeEvents.Add(newEvt);
            BindListView(jskeEvents);

            isDataChanged = true;            
        }

        private void cbbEventType_KeyDown(object sender, KeyEventArgs e)
        {
            ComboBox c = sender as ComboBox;
            if (c == null) return;
            if (c.Text == "") return;
            if (e.KeyCode == Keys.Delete)
            {
                currentEventType.TypeName.Remove(c.Text);
                cbbEventType.DataSource = null;
                cbbEventType.DataSource = currentEventType.TypeName;

                isDataChanged = true;
            }
        }

        private void DiaryForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (isDataChanged)
            {
                DialogResult res = MessageBox.Show("Do you want to save changes data?", "Notice",
                    MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
                if (res == System.Windows.Forms.DialogResult.Yes)
                {
                    doSaveDiary();
                    this.Close();
                }
                else if (res == System.Windows.Forms.DialogResult.Cancel)
                {
                    e.Cancel = true;
                }
            }
        }

        

        private void dtgrvListEvents_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (dtgrvListEvents.SelectedItems.Count > 0)
            {
                this.currentSelectedItem = dtgrvListEvents.SelectedIndices[0];
                JskeEvent evt = jskeEvents[dtgrvListEvents.SelectedIndices[0]];
                dtpkStart.Value = evt.EventStart;
                txtEventName.Text = evt.EventName;
                cbbEventType.Text = evt.EventType;
                txtDuration.Text = Convert.ToString(evt.EventDuration);

                cbbPriority.SelectedIndex = (int)evt.EventPriority;
                cbbSatisfy.SelectedIndex = (int)evt.EventSatisfy;
                txtMoney.Text = Convert.ToString(evt.Money);
                currentSelectedEvent = evt;

                btnUpdate.Enabled = true;
                btnInsertEvent.Enabled = false;
            }
            else
            {
                txtEventName.Clear();
                txtDuration.Text = "0";
                btnUpdate.Enabled = false;
                btnInsertEvent.Enabled = true;
            }
        }

        private void cbbViewEventTime_SelectedIndexChanged(object sender, EventArgs e)
        {
            _viewTo = DateTime.Now;
            int timeSpan = cbbViewEventTime.SelectedIndex;

            switch (timeSpan)
            {
                case 0:
                    _viewFrom = _viewTo.AddDays(-1.0);
                    break;
                case 1:
                    _viewFrom = _viewTo.AddDays(-7.0);
                    break;
                case 2:
                    _viewFrom = _viewTo.AddDays(-30.0);
                    break;
                case 3:
                    _viewFrom = dtpkViewFrom.MinDate;
                    _viewTo = DateTime.Now.Date.AddYears(100);
                    break;
                default:
                    break;
            }
            dtpkViewFrom.Value = _viewFrom;
            dtpkViewTo.Value = _viewTo;
            dtpkViewTo.Enabled = dtpkViewFrom.Enabled = cbbViewEventTime.Text == "Custom";
        }

        private void dtgrvListEvents_DoubleClick(object sender, EventArgs e)
        {
            if (dtgrvListEvents.SelectedItems.Count > 0)
            {
                JskeEvent evt = jskeEvents[dtgrvListEvents.SelectedIndices[0]];
                FrmEditEvent f = new FrmEditEvent(evt, cbbEventType.DataSource);
                if (DialogResult.OK == f.ShowDialog())
                {
                    currentEventType.Add(cbbEventType.Text);
                    loadEventTypeData(currentEventType);
                    cbbEventType.Text = currentSelectedEvent.EventType;

                    BindListView(jskeEvents);
                    isDataChanged = true;
                }
            }
        }

        private void btnShowInCLD_Click(object sender, EventArgs e)
        {
            CalendarForm cldForm = new CalendarForm(this);
            cldForm.ShowDialog(this);
        }
        Boolean isSortedSatisfy = true;
        private void dtgrvListEvents_ColumnClick(object sender, ColumnClickEventArgs e)
        {
            int col = e.Column;
            if (col == 0)
            {
                if (isSortedSatisfy)
                {
                    jskeEvents.Sort(delegate(JskeEvent e1, JskeEvent e2)
                    {
                        return e1.EventStart.CompareTo(e2.EventStart);
                    });
                    isSortedSatisfy = false;
                    BindListView(jskeEvents);
                }
                else
                {
                    jskeEvents.Sort(delegate(JskeEvent e1, JskeEvent e2)
                    {
                        return e2.EventStart.CompareTo(e1.EventStart);
                    });
                    isSortedSatisfy = true;
                    BindListView(jskeEvents);
                }
            }
            else if (col == 1)
            {
                if (isSortedSatisfy)
                {
                    jskeEvents.Sort(delegate(JskeEvent e1, JskeEvent e2)
                    {
                        return e1.EventType.CompareTo(e2.EventType);
                    });
                    isSortedSatisfy = false;
                    BindListView(jskeEvents);
                }
                else
                {
                    jskeEvents.Sort(delegate(JskeEvent e1, JskeEvent e2)
                    {
                        return e2.EventType.CompareTo(e1.EventType);
                    });
                    isSortedSatisfy = true;
                    BindListView(jskeEvents);
                }
            }
            else if (col == 2)
            {
                if (isSortedSatisfy)
                {
                    jskeEvents.Sort(delegate(JskeEvent e1, JskeEvent e2)
                    {
                        return e1.EventName.CompareTo(e2.EventName);
                    });
                    isSortedSatisfy = false;
                    BindListView(jskeEvents);
                }
                else
                {
                    jskeEvents.Sort(delegate(JskeEvent e1, JskeEvent e2)
                    {
                        return e2.EventName.CompareTo(e1.EventName);
                    });
                    isSortedSatisfy = true;
                    BindListView(jskeEvents);
                }
            }
            else if (col == 3)
            {
                if (isSortedSatisfy)
                {
                    jskeEvents.Sort(delegate(JskeEvent e1, JskeEvent e2)
                    {
                        return e1.EventDuration.CompareTo(e2.EventDuration);
                    });
                    isSortedSatisfy = false;
                    BindListView(jskeEvents);
                }
                else
                {
                    jskeEvents.Sort(delegate(JskeEvent e1, JskeEvent e2)
                    {
                        return e2.EventDuration.CompareTo(e1.EventDuration);
                    });
                    isSortedSatisfy = true;
                    BindListView(jskeEvents);
                }
            }
            else if (col == 4)
            {
                if (isSortedSatisfy)
                {
                    jskeEvents.Sort(delegate(JskeEvent e1, JskeEvent e2)
                    {
                        return e1.EventPriority.CompareTo(e2.EventPriority);
                    });
                    isSortedSatisfy = false;
                    BindListView(jskeEvents);
                }
                else
                {
                    jskeEvents.Sort(delegate(JskeEvent e1, JskeEvent e2)
                    {
                        return e2.EventPriority.CompareTo(e1.EventPriority);
                    });
                    isSortedSatisfy = true;
                    BindListView(jskeEvents);
                }
            }
            else if (col == 5)
            {
                if (isSortedSatisfy)
                {
                    jskeEvents.Sort(delegate(JskeEvent e1, JskeEvent e2)
                    {
                        return e1.EventSatisfy.CompareTo(e2.EventSatisfy);
                    });
                    isSortedSatisfy = false;
                    BindListView(jskeEvents);
                }
                else
                {
                    jskeEvents.Sort(delegate(JskeEvent e1, JskeEvent e2)
                    {
                        return e2.EventSatisfy.CompareTo(e1.EventSatisfy);
                    });
                    isSortedSatisfy = true;
                    BindListView(jskeEvents);
                }
            }
            else if (col == 6)
            {
                if (isSortedSatisfy)
                {
                    jskeEvents.Sort(delegate(JskeEvent e1, JskeEvent e2)
                    {
                        return e1.TaskName.CompareTo(e2.TaskName);
                    });
                    isSortedSatisfy = false;
                    BindListView(jskeEvents);
                }
                else
                {
                    jskeEvents.Sort(delegate(JskeEvent e1, JskeEvent e2)
                    {
                        return e2.TaskName.CompareTo(e1.TaskName);
                    });
                    isSortedSatisfy = true;
                    BindListView(jskeEvents);
                }
            }
            else if (col == 7)
            {
                if (isSortedSatisfy)
                {
                    jskeEvents.Sort(delegate(JskeEvent e1, JskeEvent e2)
                    {
                        return e1.ProjectName.CompareTo(e2.ProjectName);
                    });
                    isSortedSatisfy = false;
                    BindListView(jskeEvents);
                }
                else
                {
                    jskeEvents.Sort(delegate(JskeEvent e1, JskeEvent e2)
                    {
                        return e2.ProjectName.CompareTo(e1.ProjectName);
                    });
                    isSortedSatisfy = true;
                    BindListView(jskeEvents);
                }
            }
            else if (col == 8)
            {
                if (isSortedSatisfy)
                {
                    jskeEvents.Sort(delegate(JskeEvent e1, JskeEvent e2)
                    {
                        return e1.WorkingHourName.CompareTo(e2.WorkingHourName);
                    });
                    isSortedSatisfy = false;
                    BindListView(jskeEvents);
                }
                else
                {
                    jskeEvents.Sort(delegate(JskeEvent e1, JskeEvent e2)
                    {
                        return e2.WorkingHourName.CompareTo(e1.WorkingHourName);
                    });
                    isSortedSatisfy = true;
                    BindListView(jskeEvents);
                }
            }
            else if (col == 9)
            {
                if (isSortedSatisfy)
                {
                    jskeEvents.Sort(delegate(JskeEvent e1, JskeEvent e2)
                    {
                        return e1.TaskPriority.CompareTo(e2.TaskPriority);
                    });
                    isSortedSatisfy = false;
                    BindListView(jskeEvents);
                }
                else
                {
                    jskeEvents.Sort(delegate(JskeEvent e1, JskeEvent e2)
                    {
                        return e2.TaskPriority.CompareTo(e1.TaskPriority);
                    });
                    isSortedSatisfy = true;
                    BindListView(jskeEvents);
                }
            }
            else if (col == 10)
            {
                if (isSortedSatisfy)
                {
                    jskeEvents.Sort(delegate(JskeEvent e1, JskeEvent e2)
                    {
                        return e1.Money.CompareTo(e2.Money);
                    });
                    isSortedSatisfy = false;
                    BindListView(jskeEvents);
                }
                else
                {
                    jskeEvents.Sort(delegate(JskeEvent e1, JskeEvent e2)
                    {
                        return e2.Money.CompareTo(e1.Money);
                    });
                    isSortedSatisfy = true;
                    BindListView(jskeEvents);
                }
            }
        }

       
        private void onKeyDown(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)27)
            {
                this.Close();
            }
        }

        private void btnExit_Click_1(object sender, EventArgs e)
        {
            this.Close();
        }

    }
}
